#ifndef G3_ZIPSTREAM_H
#define G3_ZIPSTREAM_H

#include "f_zstream.h"
#include "zlib.h"

namespace G3 {

class ZIPSTREAM: public ZSTREAM {
	public:
		ZIPSTREAM (G3::STREAM *stream);
		~ZIPSTREAM ();

//==============================================================================
// Opens a ZFILESTREAM either for Deflating or Inflating data..
//
//		byte OpenFlags				Flags for the stream
//				ZSTREAM_DEFLATE		Opens for deflating (compressed buffering)
//				ZSTREAM_INFLATE		Opens for inflating (decompressed reading)
//
//		int Level					Compression level
//				-1					Default, level 6
//				0					No compression at all
//				1 ... 9				Lowest ... Hightest compression
//
//	Returns true if successful
//==============================================================================
		bool Open (byte openFlags = ZSTREAM_INFLATE, int level = Z_DEFAULT_COMPRESSION);

//==============================================================================
// Closes the ZFILESTREAM
//==============================================================================
		void Close ();

//==============================================================================
// Compresses data and adds it to the stream buffer
//
//		void *Pointer			Pointer to a memory block from where to compress
//
//		long Size				Number of bytes to compress
//
//	NOTE:: To end the compression, either Pointer has to become NULL or Size 0
//
//	Returns true on success
//==============================================================================
		bool Deflate (byte *pointer = NULL, long size = 0);

//==============================================================================
// Reads data from the stream and decompresses it
//
//		void *Pointer			Pointer to a memory block where the data is stored
//
//		long Size				Number of bytes saved at the Pointer
//
//	Returns the number of bytes stored at Pointer
//==============================================================================
		long Inflate (byte *pointer, long size);

//==============================================================================
// Reads data into the stream and decompresses it
//
//		void *Pointer			Pointer to a memory block where the data is read from
//
//		long Size				Number of bytes saved into the stream
//
//	Returns the number of bytes stored into the stream
//==============================================================================
		long InflateIn (byte *pointer, long size);

//==============================================================================
// Compresses data from the stream
//
//		void *Pointer			Pointer to a memory block where to compress
//
//		long Size				Number of bytes to compress
//
//	NOTE:: To end the compression, Size has to become 0
//
//	Returns true on success
//==============================================================================
		long DeflateOut (byte *pointer = NULL, long size = 0);

//==============================================================================
// Reads data from a file and decompresses it
//
//		const char *Filename	Name of the file to buffer
//
//		long Size				Number of bytes to buffer
//				-1, 0			Buffers the whole file into the stream
//
//		long Position			Where in the file should we start reading
//
//	Returns true on success
//==============================================================================
		long InflateFromFile (const string &filename, long size = -1, long position = 0);

//==============================================================================
// Reads data from the stream and compresses it into a file
//
//		const char *Filename	Name of the file to store the data in
//
//		long Size				Number of bytes read from the stream
//				-1, 0			Reads the whole stream buffer
//
//		long Position			Where to write into the file
//
//	Returns the number of bytes read
//==============================================================================
		long DeflateToFile (const string &filename, long size = -1, long position = 0);

	protected:
		z_stream zStream;
};

}

#endif
